package com.zys.sac.core.helper;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.HashMap;
import java.util.Map;

/**
 * 内存互斥token管理器，如果使用该token管理器，同一个用户将不允许重复登录
 *
 * Created by zhongjunkai on 2023/2/23.
 */
public class InMemoryMutexTokenManager implements TokenManager {

    protected TimedCache<String, Object> tokenCache;

    protected long expiredTime;

    public InMemoryMutexTokenManager(long expiredTime) {
        this.expiredTime = expiredTime;
        tokenCache = CacheUtil.newTimedCache(this.expiredTime);
        //10秒钟定时清理过期缓存
        tokenCache.schedulePrune(10000);
    }

    @Override
    public String createAndSaveToken(UserDetails userDetails) {
        return this.createAndSaveToken(userDetails, this.expiredTime);
    }

    @Override
    public String createAndSaveToken(UserDetails userDetails, long expired) {
        String token = generateToken(userDetails);
        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        data.put("user", userDetails);
        tokenCache.put(createCacheKey(token), data, expired);
        return token;
    }

    @Override
    public void renewalToken(String token) {
        this.renewalToken(token, this.expiredTime);
    }

    @Override
    public void renewalToken(String token, long expired) {
        Map<String, Object> map = (Map<String, Object>) this.tokenCache.get(createCacheKey(token));
        tokenCache.put(createCacheKey(token), map, expired);
    }

    @Override
    public UserDetails getUserDetails(String token) {
        String cacheKey = createCacheKey(token);
        Map<String, Object> map = (Map<String, Object>) this.tokenCache.get(cacheKey);
        String cacheToken = (String) map.get("token");
        if (!token.equals(cacheToken)) {
            return null;
        }
        return (UserDetails) map.get("user");
    }

    @Override
    public void invalidToken(String token) {
        this.tokenCache.remove(createCacheKey(token));
    }

}
